package com.hadoop.log;

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zhaochao on 2017/5/26.
 */
public class CDNCount extends Configured implements Tool {


    public static IntWritable getHour(String line) {
        Matcher matcher = Pattern.compile("2017:(\\d{2}):").matcher(line);
        if (matcher.find()) {
            return new IntWritable(Integer.parseInt(matcher.group(1)));
        } else {
            return new IntWritable(0);
        }
    }

    public static LongWritable getHttpSize(String line) {
        Matcher matcher = Pattern.compile(" (200|206|304) ([0-9]+) ").matcher(line);
        if (matcher.find()) {
            return new LongWritable(Integer.parseInt(matcher.group(2)));
        } else {
            return new LongWritable(0);
        }
    }


    public static class Map extends Mapper<LongWritable, Text, IntWritable, LongWritable> {

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            context.write(getHour(line), getHttpSize(line));
        }
    }


    public static class Reduce extends Reducer<IntWritable, LongWritable, IntWritable, LongWritable> {
        @Override
        protected void reduce(IntWritable key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
            Long size = 0L;
            for (LongWritable value : values) {
                size += value.get();
            }
            System.out.println(key + " " + size);
            context.write(key, new LongWritable(size));
        }
    }




    public int run(String[] args) throws Exception {
        Job job = new Job(getConf());
        job.setJarByClass(CDNCount.class);
        job.setJobName("CDNCount");


        job.setOutputKeyClass(IntWritable.class);
        job.setOutputValueClass(LongWritable.class);


        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);


        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        boolean success = job.waitForCompletion(true);
        return success ? 0 : 1;

    }

    public static void main(String[] args) throws Exception {
        int res = ToolRunner.run(new CDNCount(), args);
         System.exit(res);


    }
}
